#pragma once

#include <QString>
#include <QIcon>
#include <QUuid>
#include <QDateTime>
#include <QFile>
#include <QFileInfo>
#include <QDebug>

//创建命名空间
namespace model
{
///////////////////////////////////////////
/// 工具函数，后续很多模块可能都用到
///////////////////////////////////////////

static inline QString getFileName(const QString& path)
{
    QFileInfo fileinfo(path);
    return fileinfo.fileName();
}

//封装一个宏 “宏” 作为打印日志的方式
#define TAG QString("[%1][%2]").arg(model::getFileName(__FILE__),QString::number(__LINE__))
#define LOG() qDebug().noquote() << TAG

// 要求函数的定义如果写在 .h 中, 必须加 static 或者 inline (当然两个都加也可以), 避免链接阶段出现 "函数重定义" 的问题.
static inline QString formatTime(int64_t timestamp)
{
    // 先把时间戳, 转换成 QDateTime 对象
    QDateTime dateTime = QDateTime::fromSecsSinceEpoch(timestamp);
    // 把 QDateTime 对象转成 "格式化时间"
    return dateTime.toString("MM-dd HH:mm:ss");
}


// 通过这个函数得到 秒级 的时间
static inline int64_t getTime()
{
    return QDateTime::currentSecsSinceEpoch();
}

//根据 QByteArray，转成QIcon
static inline QIcon makeIcon(const QByteArray& byteArray)
{
    QPixmap pixmap;
    pixmap.loadFromData(byteArray);
    QIcon icon(pixmap);
    return icon;
}

// 读写文件操作.
// 从指定文件中, 读取所有的二进制内容. 得到一个 QByteArray
static inline QByteArray loadFileToByteArray(const QString& path) {
    QFile file(path);
    bool ok = file.open(QFile::ReadOnly);
    if (!ok) {
        LOG() << "文件打开失败!";
        return QByteArray();
    }
    QByteArray content = file.readAll();
    file.close();
    return content;
}

// 把 QByteArray 中的内容, 写入到某个指定文件里
static inline void writeByteArrayToFile(const QString& path, const QByteArray& content) {
    QFile file(path);
    bool ok = file.open(QFile::WriteOnly);
    if (!ok) {
        LOG() << "文件打开失败!";
        return;
    }
    file.write(content);
    file.flush();
    file.close();
}

///////////////////////////////////////////
/// 用户信息
///////////////////////////////////////////

class UserInfo
{
public:
    QString userId = "";          //用户编号
    QString nickname = "";        //用户昵称
    QString description = "";     //用户签名
    QString phone = "";           //手机号
    QIcon avatar;                 //用户头像
};

///////////////////////////////////////////
/// 消息信息
///////////////////////////////////////////

enum MessageType
{
    TEXT_TYPE , // 文本消息
    IMAGE_TYPE, // 图片消息
    FILE_TYPE,  //文件消息
    SPEECH_TYPE  //语音消息
};



class Message
{
public:
    QString messageId = "";         // 消息编号
    QString chatSessionId = "";     // 消息所属会话的编号
    QString time = "";              // 消息的时间，通过“格式化” 时间的方式来表示，形如06-07 12：00：00
    MessageType messageType;        // 消息类型
    UserInfo sender;                // 发送者的信息
    QByteArray content;             // 消息正文内容
    QString fileId = "";            // 文件的身份标识，当消息类型为文件图片，语音的时候，才有效，当消息类型为文本的则为“”
    QString fileName = "";          // 文件名称，只是当消息类型为 文件消息，才有效，其他消息均为“”

    // 此处 extraInfo 目前只是在消息类型为文件消息时, 作为 "文件名" 补充.
    static Message makeMessage(MessageType messageType, const QString& chatSessionId, const UserInfo& sender,
                               const QByteArray& content, const QString& extraInfo)
    {
        if (messageType == TEXT_TYPE)
        {
            return makeTextMessage(chatSessionId, sender, content);
        } else if (messageType == IMAGE_TYPE)
        {
            return makeImageMessage(chatSessionId, sender, content);
        } else if (messageType == FILE_TYPE)
        {
            return makeFileMessage(chatSessionId, sender, content, extraInfo);
        } else if (messageType == SPEECH_TYPE)
        {
            return makeSpeechMessage(chatSessionId, sender, content);
        } else
        {
            // 触发了未知的消息类型
            return Message();
        }
    }

public:
    // 通过这个方法生成唯一的 messageId
    static QString makeId() {
        return "M" + QUuid::createUuid().toString().sliced(25, 12);
    }

    static Message makeTextMessage(const QString& chatSessionId, const UserInfo& sender, const QByteArray& content)
    {
        Message message;
        // 此处需要确保, 设置的 messageId 是 "唯一" 的
        message.messageId = makeId();
        message.chatSessionId = chatSessionId;
        message.sender = sender;
        message.time = formatTime(getTime()); // 生成一个格式化时间
        message.content = content;
        message.messageType = TEXT_TYPE;
        // 对于文本消息来说, 这俩属性不使用, 设为 ""
        message.fileId = "";
        message.fileName = "";
        return message;
    }

    static Message makeImageMessage(const QString& chatSessionId, const UserInfo& sender, const QByteArray& content)
    {
        Message message;
        message.messageId = makeId();
        message.chatSessionId = chatSessionId;
        message.sender = sender;
        message.time = formatTime(getTime());
        message.content = content;
        message.messageType = IMAGE_TYPE;
        // fileId 后续使用的时候再进一步设置
        message.fileId = "";
        // fileName 不使用, 直接设为 ""
        message.fileName = "";
        return message;
    }

    static Message makeFileMessage(const QString& chatSessionId, const UserInfo& sender, const QByteArray& content, const QString& fileName)
    {
        Message message;
        message.messageId = makeId();
        message.chatSessionId = chatSessionId;
        message.sender = sender;
        message.time = formatTime(getTime());
        message.content = content;
        message.messageType = FILE_TYPE;
        // fileId 后续使用的时候进一步设置
        message.fileId = "";
        message.fileName = fileName;
        return message;
    }

    static Message makeSpeechMessage(const QString& chatSessionId, const UserInfo& sender, const QByteArray& content)
    {
        Message message;
        message.messageId = makeId();
        message.chatSessionId = chatSessionId;
        message.sender = sender;
        message.time = formatTime(getTime());
        message.content = content;
        message.messageType = SPEECH_TYPE;
        // fileId 后续使用的时候进一步设置
        message.fileId = "";
        // fileName 不使用, 直接设为 ""
        message.fileName = "";
        return message;
    }
};

///////////////////////////////////////////
/// 会话信息
///////////////////////////////////////////

class ChatSessionInfo
{
public:
    QString chatSessionId = "";           // 会话编号
    QString chatSessionName = "";         // 会话名字，如果会话是单聊，名字就是对方的昵称，如果是群聊名字就是群聊的名称
    Message lastMessage;                  // 表示最新消息
    QIcon avater;                         // 会话头像，如果会话是单聊，头像就是对方的头像，如果是群聊，头像群聊的头像
    QString userId = "";                  // 对于单聊来说，表示对方用户的id，对于群聊设置为“”
};


}//end model























